//TileForwardDisplacementMappingFX.h
//Created By Daniel Bowler
//Created 02/12/13
//
//Basic Displacement mapping effect.

#pragma once

#include "AbstractFX.h"

class TileForwardDisplacementMappingFX : public AbstractFX
{
	//Shader manager will create & destroy an instance of this class.
	friend ShaderManager;
public:
	//Vertex layout
	struct PerVertexData
	{
		XMFLOAT3 PosL;		//Local position
		XMFLOAT3 NormalL;   //Local Normal Vector
		XMFLOAT2 Tex;		//UV coords
		XMFLOAT3 TangentL;  //Tangent vector (T of our TBN basis which defines tangent space)
	};

	//Setters for the shader variables and resources.
	void SetShaderResources(ID3D11ShaderResourceView* dispMap,
		ID3D11ShaderResourceView* tex, 
		ID3D11ShaderResourceView* hm);

	void SetPerFrameCbuffer(XMFLOAT3& eye, 
		DirectionalLight* dLights, unsigned dLightCount,
		ID3D11ShaderResourceView* lightListIndexBuffer, 
		ID3D11ShaderResourceView* lightListStartEndBuffer);

	void SetPerObjectCbuffer(CXMMATRIX& world, CXMMATRIX& viewProj,
		CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj,
		CXMMATRIX& texTrans, Material mat, 
		CXMMATRIX& worldView, CXMMATRIX &view);

	void SetCbufferTessData(float heightScale,
		float maxTessDist, float minTessDist, 
		float maxTessFact, float minTessFact);

	//Sets hemispherical ambient colour data
	void SetHemisphericalData(XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange);

	//Set SSAO Map and transform data
	void SetSSAOData(ID3D11ShaderResourceView* ssaoTex, CXMMATRIX &transform);

	//Sets the environment map - Note Material::Reflection determins how
	//much of the enviromnet is reflected on the model. Very shiny models
	//should have more reflectivity and mat models less. Also, flat models
	//should NOT have any reflectivity because the effect looks shit. 
	void SetEnvironmentMap(ID3D11ShaderResourceView* envCubeMap);

	//Tile forward setters
	void SetLightListBuffer(ID3D11ShaderResourceView* lightListBuffer);
	void SetRTDimensions(unsigned width, unsigned height);
	
	//Sets shadow map
	void SetShadowMap(ID3D11ShaderResourceView* shadowMap);
	void SetShadowMapMatricies(CXMMATRIX &view, CXMMATRIX &proj, CXMMATRIX &toTex);

private:
	//Constructor and destructor
	TileForwardDisplacementMappingFX(ID3D11Device* device);
	~TileForwardDisplacementMappingFX();
	//Disable copy constructor and = operator
	TileForwardDisplacementMappingFX(TileForwardDisplacementMappingFX& other);
	TileForwardDisplacementMappingFX& operator= (TileForwardDisplacementMappingFX& other);

	//Override these to aid in creating the FX class properly.
	void InitInputLayout(ID3D11Device* device);
	void InitShaderVariablePointers();

private:
	//Shader Variables.
	//
	//Per frame
	ID3DX11EffectVariable* dLightVar;
	ID3DX11EffectScalarVariable* dLightCountVar;
	ID3DX11EffectVectorVariable* eyePosWVar;
	//
	//Per object
	ID3DX11EffectMatrixVariable* worldVar;
	ID3DX11EffectMatrixVariable* viewProjVar;
	ID3DX11EffectMatrixVariable* worldInvTransVar;
	ID3DX11EffectMatrixVariable* worldViewProjVar;
	ID3DX11EffectMatrixVariable* textureTransformVar;
	ID3DX11EffectVariable* materialVar;
	//
	//Shader Resources (SRVs)
	ID3DX11EffectShaderResourceVariable* dispMapVar;
	ID3DX11EffectShaderResourceVariable* textureMapVar;
	ID3DX11EffectShaderResourceVariable* hmVar;
	//
	//Per object tessallation factors
	ID3DX11EffectScalarVariable* heightScaleVar;
	ID3DX11EffectScalarVariable* maxTessDistanceVar;
	ID3DX11EffectScalarVariable* minTessDistanceVar;
	ID3DX11EffectScalarVariable* maxTessFactorVar;
	ID3DX11EffectScalarVariable* minTessFactorVar;

	//TileForward Rendering variablaes. 
	ID3DX11EffectShaderResourceVariable* llbVar;
	ID3DX11EffectShaderResourceVariable* llibVar;
	ID3DX11EffectShaderResourceVariable* llsebVar;
	//Render dimensions
	ID3DX11EffectScalarVariable* rtWidthVar;
	ID3DX11EffectScalarVariable* rtHeightVar;
	
	//Hemispheric Ambient lighting colours
	ID3DX11EffectVectorVariable* hemiColDownVar;
	ID3DX11EffectVectorVariable* hemiColRangeVar;

	//SSAO
	ID3DX11EffectMatrixVariable* worldViewVar;
	ID3DX11EffectMatrixVariable* viewVar;
	ID3DX11EffectShaderResourceVariable* ssaoMapVar;
	ID3DX11EffectMatrixVariable* ssaoWorldViewProjTexVar;

	//Environment map
	ID3DX11EffectShaderResourceVariable* envMapVar;
	
	//Shadow Map
	ID3DX11EffectShaderResourceVariable* shadowMapVar;
	ID3DX11EffectMatrixVariable* shadowMapViewVar;
	ID3DX11EffectMatrixVariable* shadowMapProjVar;
	ID3DX11EffectMatrixVariable* shadowMapToTexVar;
};